package it.trekker.prefetch;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;

import it.trekker.dao.Excursion;
import it.trekker.dao.GPSCoordinate;

public class ExcursionsCache implements IExcursionsCache {

	protected static final Logger logger = Logger.getLogger(ExcursionsCache.class.getCanonicalName());
	
	protected Map<Integer, Excursion> excursions;
	

	
	
	public ExcursionsCache() {
		excursions = new HashMap<Integer, Excursion>();
	}
	
	
	synchronized public Excursion getExcursionById(int id) {
		if(excursions != null)
			return excursions.get(id);
		
		return null;
	}


	synchronized public int addExcursion(Excursion excursion) {
		if(excursion != null && excursions != null && !excursions.containsKey(excursion.getId())) {
			excursions.put(new Integer(excursion.getId()), excursion);
			return excursion.getId();
		}
		
		return 0;
	}
	
	
	synchronized public List<Excursion> getAllCachedExcursions() {
		return new ArrayList<Excursion>(excursions.values());
	}
	
	
	synchronized private List<Excursion> getExcursionsFromCache(GPSCoordinate point, double radius, Excursion excluded) {
		List<Excursion> result = new ArrayList<Excursion>();
		
		Iterator<Excursion> it = excursions.values().iterator();
		while(it.hasNext()) {
			Excursion exc = it.next();
			if(excluded == null || excluded.getId() != exc.getId()) {
				if(GPSCoordinate.distanceBetween(point, exc.getStartPoint()) <= radius)
					result.add(exc);
			}
		}
		
		return result;
	}
	
	
	synchronized public List<Excursion> getExcursionsFromCache(Excursion excursion, double radius) {
		if(excursion != null)
			return getExcursionsFromCache(excursion.getStartPoint(), radius, excursion);
		return null;
	}
	
	
	synchronized public List<Excursion> getExcursionsFromCache(GPSCoordinate point, double radius) {
		if(point != null)
			return getExcursionsFromCache(point, radius, null);
		return null;
	}

	
	synchronized public void invalidateCache() {
		if(excursions != null && excursions.size() > 0)
			excursions.clear();
	}
	
	
	public int getSize() {
		return excursions.size();
	}
	
	
	public void logAllCache() {
		logger.info("---- Cache content ----");
		for(Excursion excursion : excursions.values()) {
			logger.info(excursion);
		}
		logger.info("-----------------------");
	}

}
